//
// Created by Y7000 on 2024/6/27.
//
/*
 * 普通函数调用时可以发生隐式类型转换
 * 函数模板使用时，如果利用自动类型推导，不会发生隐式类型转换
 * 函数模板使用显式指定类型，可以发生隐式类型转换
 */

/*
 * 普通函数和函数模板都可以使用时，优先调用普通模板
 * 可以通过空模板参数列表来强制调用函数模板  myPrint<>(arr, len);
 * 函数模板可以发生重载
 * 如果函数模板可以产生更好的匹配，优先调用函数模板(如果函数模板可以精确匹配参数列表则使用函数模板。否则使用普通函数的隐式类型转化)
 */

/*
 * 模板不是万能的，对于一些类的对比需要具体化做特殊实现
 *
 */

/*
 * 当子类继承父类是一个模板时，子类的声明中需要指定父类中的T类型
 如果想要灵活指定父类中T的类型，那子类也需要变成类模板
 */
#include <iostream>

using namespace std;

template<typename T> //声明一个模板，告诉编译器T是一个模板参数
void mySwap(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

void test() {
    int a = 10;
    int b = 20;
    /*自动类型推导*/
    //自动类型推导，必须推导出一致的数据类型T才可使用
    //模板必须要确定T的类型才可以使用

    mySwap(a, b);

    /*显示指定类型*/
    mySwap<int>(a, b);
}

template<typename T>
void mySort(T arr[], int len) {
    for (int i = 0; i < len; ++i) {
        int max = i; //认定最大值的下标
        for (int j = i + 1; j < len; ++j) {
            //认定的最大值比j的小，则将j标记为最大值下标
            if (arr[max] < arr[j]) {
                max = j;
            }
        }
        if (max != i) {
            mySwap(arr[max], arr[i]);
        }
    }
}

template<typename T>
void myPrint(T arr[], int len) {
    for (int i = 0; i < len; ++i) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

void sortCharArr() {
    char charArr[] = "badcfe";
    int len = sizeof(charArr) / sizeof(charArr[0]);
    mySort(charArr, len);
    myPrint(charArr, len);
}

void sortIntArr() {
    int intArr[] = {7, 5, 3, 2, 1, 4, 6};
    int len = sizeof(intArr) / sizeof(intArr[0]);
    mySort(intArr, len);
    myPrint(intArr, len);
}

template<class NameType, class AgeType=int>
class Person {
public:
    Person(NameType name, AgeType age) {
        this->m_Name = name;
        this->m_Age = age;
    }

    NameType m_Name;
    AgeType m_Age;
};

int main() {
    sortCharArr();
    sortIntArr();
    Person<string> person("11", 1);
    return 0;
}
